﻿#region Librerias

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using ESF.General;
using ESF.General.Commands;

#endregion


namespace ESF.WinForms.Controls.ImageControls
{
	public partial class uscImageEditor : UserControl
	{
		#region Miembros

		private CommandManager<Image> _CommandManager;

		private FileInfo _ImageFile;

		#endregion


		#region Propiedades

		public string ImageFilename
		{
			set 
			{
				_ImageFile = new FileInfo (value);

				_CommandManager = new CommandManager<Image> (Image.FromFile (value));

				imgImage.Image = _CommandManager.CurrentObject;

				imgImage.Width = imgImage.Image.Width;
				imgImage.Height = imgImage.Image.Height;

				lblImageHeight.Text = string.Format ("{0:##}", imgImage.Image.PhysicalDimension.Height);
				lblImageWidth.Text = string.Format ("{0:##}", imgImage.Image.PhysicalDimension.Width);
				
				lblImageSize.Text = TextHelper.ToStringBytes (_ImageFile.Length);
				lblImageName.Text = _ImageFile.Name;

				RestoreAdjustValues ();

				Enabled = true;
			}
		}

		#endregion


		#region Constructor
		
		public uscImageEditor()
		{
			InitializeComponent();

			Enabled = false;
		}

		#endregion


		#region Funciones

		public void UndoLast ()
		{
			int value;


			_CommandManager.UndoLast ();

			if (_CommandManager.GetCurrentCommandParameter<int> ("trkImageContrast.Value", out value))
			{
				trkImageContrast.Value = value;
			}

			if (_CommandManager.GetCurrentCommandParameter<int> ("trkImageBrightness.Value", out value))
			{
				trkImageBrightness.Value = value;
			}

			RefreshImage ();
		}


		public void RedoLast ()
		{
			_CommandManager.RedoLast ();

			RefreshImage ();
		}


		public void SaveChanges ()
		{
			try
			{
				// TODO: Actualizar el tumbnail de la edicion OnSaveImage

				_CommandManager.CurrentObject.Save (_ImageFile.FullName);

				WinFormsHelper.ShowInfo (this, string.Format ("La imagen {0} ha sido guardada", _ImageFile.Name));
			}
			catch (Exception pEx)
			{
				WinFormsHelper.ShowError (this, pEx);
			}
		}


		private void RefreshImage ()
		{
			/*if (trkImageZoom.Value != 100)
			{
				imgImage.Image = 
					ImageHelper.GenerateTumbnail (
						_CommandManager.CurrentObject,
						(int) Math.Ceiling (_CommandManager.CurrentObject.Width * (trkImageZoom.Value / 100.0)), 
						(int) Math.Ceiling (_CommandManager.CurrentObject.Height * (trkImageZoom.Value / 100.0)));
			}
			else
			{
				imgImage.Image = _CommandManager.CurrentObject;
			}

			imgImage.Width = imgImage.Image.Width;
			imgImage.Height = imgImage.Image.Height;

			imgImage.Invalidate ();
			imgImage.Refresh ();
			*/
			Invalidate ();
			Refresh ();
		}


		private void RestoreAdjustValues ()
		{
			trkImageBrightness.Value = 0;
			trkImageContrast.Value = 0;
		}

		#endregion


		#region Eventos

		private void btnDoImageGrayScale_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			_CommandManager.Add (
				new ConcreteCommand <Image> (
					delegate (Image pCurrentImage, ref Dictionary<string, object> pParameters) 
					{
						ImageHelper.GrayScale ((Bitmap) pCurrentImage);

						return pCurrentImage;
					}));

			RefreshImage ();
		}

		
		private void trkImageBrightness_Scroll(object sender, EventArgs e)
		{
			_CommandManager.Add (
				new ConcreteCommand <Image> (
					delegate (Image pCurrentImage, ref Dictionary<string, object> pParameters) 
					{
						pCurrentImage = _CommandManager.ClonedOriginalObject;
						
						pParameters.Add ("trkImageBrightness.Value", trkImageBrightness.Value);

						ImageHelper.Brightness ((Bitmap) pCurrentImage, trkImageBrightness.Value);

						return pCurrentImage;
					}));

			RefreshImage ();
		}
		

		private void trkImageContrast_Scroll(object sender, EventArgs e)
		{
			_CommandManager.Add (
				new ConcreteCommand <Image> (
					delegate (Image pCurrentImage, ref Dictionary<string, object> pParameters) 
					{
						pCurrentImage = _CommandManager.ClonedOriginalObject;

						pParameters.Add ("trkImageContrast.Value", trkImageContrast.Value);

						ImageHelper.Contrast ((Bitmap) pCurrentImage, trkImageContrast.Value);

						return pCurrentImage;
					}));

			RefreshImage ();
		}

		
		private void btnDoRotateImageLeft_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			_CommandManager.Add (
				new ConcreteCommand <Image> (
					delegate (Image pCurrentImage, ref Dictionary<string, object> pParameters) 
					{
						pCurrentImage.RotateFlip (RotateFlipType.Rotate270FlipNone);

						return pCurrentImage;
					}));
			
			RefreshImage ();
		}


		private void btnDoRotateImageRight_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			_CommandManager.Add (
				new ConcreteCommand <Image> (
					delegate (Image pCurrentImage, ref Dictionary<string, object> pParameters) 
					{
						pCurrentImage.RotateFlip (RotateFlipType.Rotate90FlipNone);

						return pCurrentImage;
					}));
			
			RefreshImage ();
		}


		private void btnDoImageHorizontalFlip_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			_CommandManager.Add (
				new ConcreteCommand <Image> (
					delegate (Image pCurrentImage, ref Dictionary<string, object> pParameters) 
					{
						pCurrentImage.RotateFlip (RotateFlipType.RotateNoneFlipX);

						return pCurrentImage;
					}));
			
			RefreshImage ();
		}


		private void btnDoImageVerticalFlip_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			_CommandManager.Add (
				new ConcreteCommand <Image> (
					delegate (Image pCurrentImage, ref Dictionary<string, object> pParameters) 
					{
						pCurrentImage.RotateFlip (RotateFlipType.RotateNoneFlipY);

						return pCurrentImage;
					}));
			
			RefreshImage ();
		}

		
		private void trkImageZoom_Scroll(object sender, EventArgs e)
		{
			RefreshImage ();
		}


		private void btnRestoreOriginalImage_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			_CommandManager.Reset ();

			RestoreAdjustValues ();

			RefreshImage ();
		}
		
		#endregion

		private void button1_Click(object sender, EventArgs e)
		{
			UndoLast ();
		}

		private void button2_Click(object sender, EventArgs e)
		{
			SaveChanges ();
		}

		private void button3_Click(object sender, EventArgs e)
		{
			RedoLast ();
		}
		
	}
}
